
import React, { FC, useEffect, useState } from 'react';

import { Button, Col, Checkbox, DatePicker, Form, Input, InputNumber, Modal, Row, Spin, Table } from 'antd';

import {
    SearchTestEntityDocument,
    _CreateTestEntityInput, 
    useCreateTestEntityMutation, 
    useDeleteTestEntityMutation, 
    useSearchTestEntityQuery, 
    _UpdateTestEntityInput, 
    TestEntitySearchAttributesFragment, 
    useUpdateTestEntityMutation, 
    UpdateTestEntityMutationVariables,
    CreateTestEntityMutationVariables
} from '../../__generate/graphql-frontend'

import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
import ErrorModal from '../basic/ErrorModal';
import Search from 'antd/lib/input/Search';
import moment from 'moment';



enum ShowForm {
    None,
    Create,
    Update
}


function mapViewToInput(data: TestEntitySearchAttributesFragment): UpdateTestEntityMutationVariables {
    return {
        input: {
            id: data.id,
            stringField: data.stringField,
textField: data.textField,
integerField: data.integerField,
bigDecimalField: data.bigDecimalField,
booleanField: data.booleanField,
localDateField: data.localDateField,
localDateTimeField: data.localDateTimeField,

        }
    }
}

export const TestEntityList: FC = () => {

    const columns = [
  {
    "title": "id",
    "key": "id",
    "dataIndex": "id"
  },
  {
    "title": "stringField",
    "key": "stringField",
    "dataIndex": "stringField"
  },
  {
    "title": "textField",
    "key": "textField",
    "dataIndex": "textField"
  },
  {
    "title": "integerField",
    "key": "integerField",
    "dataIndex": "integerField"
  },
  {
    "title": "bigDecimalField",
    "key": "bigDecimalField",
    "dataIndex": "bigDecimalField"
  },
  {
    "title": "booleanField",
    "key": "booleanField",
    "dataIndex": "booleanField"
  },
  {
    "title": "localDateField",
    "key": "localDateField",
    "dataIndex": "localDateField"
  },
  {
    "title": "localDateTimeField",
    "key": "localDateTimeField",
    "dataIndex": "localDateTimeField"
  },
  {
    "title": "actions",
    "key": "actions",
    "dataIndex": "actions"
  }
]

    const [deleteId, setDeleteId] = useState<string | null>(null)
    const [showForm, setShowForm] = useState<ShowForm>(ShowForm.None)
    const [error, setError] = useState<Error | null>(null)

    const [inputParameters, setInputParameters] = useState<UpdateTestEntityMutationVariables | CreateTestEntityMutationVariables>()


    const [searchStr, setSearchStr] = useState<string>("")


    const { data, loading, error: errorQuery } = useSearchTestEntityQuery({
        variables: {
            searchStr
        }
    })
    const TestEntityList = data?.searchTestEntity.elems

    const [createTestEntityMutation, { error: errorCreate, data: dataCreate }] = useCreateTestEntityMutation()
    const [updateTestEntityMutation, { error: errorUpdate, data: dataUpdate }] = useUpdateTestEntityMutation()
    const [deleteTestEntityMutation, { error: errorDelete }] = useDeleteTestEntityMutation()



    useEffect(() => {
        const err = [errorQuery, errorCreate, errorUpdate, errorDelete].find(e => e)
        if (err) {
            setError(err)
        }

    }, [errorQuery, errorCreate, errorUpdate, errorDelete])

    useEffect(() => {
        if (dataCreate || dataUpdate)
            setShowForm(ShowForm.None)
    },
        [dataCreate, dataUpdate]
    )

    const mapToView = (list: Array<TestEntitySearchAttributesFragment>) => {
        return (
            list?.map(elem => {
                return {
                    key: elem.id ?? "",
                    id: elem.id,
                    stringField: elem.stringField,
textField: elem.textField,
integerField: elem.integerField,
bigDecimalField: elem.bigDecimalField,
booleanField: <Checkbox checked={elem.booleanField!} disabled={true} />,
localDateField: elem.localDateField,
localDateTimeField: elem.localDateTimeField,

                    actions: <>
                        <Button style={{ margin: "5px" }}
                            key={"e" + elem.id}
                            onClick={() => {
                                setInputParameters(mapViewToInput(elem))
                                setShowForm(ShowForm.Update)
                            }}
                        ><EditOutlined />
                        </Button>
                        <Button style={{ margin: "5px" }}
                            key={"d" + elem.id}
                            onClick={() => { setDeleteId(elem.id) }}
                        ><DeleteOutlined /></Button>
                    </>
                }
            })
        )
    }

    if (loading) return (<Spin tip="Loading..." />);
    if (error) return (<ErrorModal error={error} setError={setError} />)

    return (
        <>
            <Modal visible={deleteId != null}
                onCancel={() => setDeleteId(null)}
                onOk={
                    () => {
                        deleteTestEntityMutation({
                            variables: {
                                id: deleteId!
                            },
                            update: (store) => {
                                store.writeQuery({
                                    query: SearchTestEntityDocument,
                                    variables: { searchStr },
                                    data: {
                                        searchTestEntity: {
                                            elems: TestEntityList!.filter(x => x.id !== deleteId)
                                        }
                                    }
                                })
                            }
                        })
                        setDeleteId(null)
                    }
                }
            >Delete?</Modal>
            <Row style={{ margin: "5px" }}>
                <Col span="4">
                    <Button
                        onClick={() => {
                            setInputParameters({ input: {} })
                            setShowForm(ShowForm.Create)
                        }}>
                        <PlusOutlined></PlusOutlined>
                    </Button>
                </Col>
                <Col span="4">
                    <Search defaultValue={searchStr} onSearch={(value) => setSearchStr(value)} />
                </Col>
            </Row>

            <Modal visible={showForm != ShowForm.None}
                onCancel={() => setShowForm(ShowForm.None)}
                onOk={() => {
                    if (showForm == ShowForm.Create) {
                        createTestEntityMutation({
                            variables: inputParameters as CreateTestEntityMutationVariables,
                            update: (store, result) => {
                                store.writeQuery({
                                    query: SearchTestEntityDocument,
                                    variables: { searchStr },
                                    data: {
                                        searchTestEntity: {
                                            elems: [, ...TestEntityList!, result.data?.packet?.createTestEntity]
                                        }
                                    }
                                })
                            }
                        })
                    } else if (showForm == ShowForm.Update) {
                        updateTestEntityMutation({ variables: inputParameters as UpdateTestEntityMutationVariables })
                    }
                }}
            >
                {inputParameters &&
                    <TestEntityEdit
                        inputParameters={inputParameters}
                        setInputParameters={setInputParameters}
                    />
                }

            </Modal>
            {TestEntityList &&
                <Table
                    columns={columns}
                    dataSource={mapToView(TestEntityList)}
                />}

        </>
    )
}

type InputParameters = {
    inputParameters: UpdateTestEntityMutationVariables | CreateTestEntityMutationVariables,
    setInputParameters: (input: UpdateTestEntityMutationVariables | CreateTestEntityMutationVariables) => void
}

const TestEntityEdit: FC<InputParameters> = ({ inputParameters, setInputParameters }) => {

    return (
        <Form>
            
    <Form.Item label="bigDecimalField">
        <InputNumber
            value={inputParameters.input.bigDecimalField!}
            
            onChange={value => {
                const i = { ...inputParameters }
                i.input.bigDecimalField = value
                setInputParameters(i)
            }}
        />
    </Form.Item>

    <Form.Item label="booleanField">
        <Checkbox
            checked={inputParameters.input.booleanField!}
            onChange={e => {
                const i = { ...inputParameters }
                i.input.booleanField = e.target.checked
                setInputParameters(i)
            }}
        />
    </Form.Item>


    <Form.Item label="integerField">
        <InputNumber
            value={inputParameters.input.integerField!}
                onChange={value => {
                const i = { ...inputParameters }
                i.input.integerField = value
                setInputParameters(i)
            }}
        />
    </Form.Item>

    <Form.Item label="localDateField">
        <DatePicker
            value={inputParameters.input.localDateField ? moment(inputParameters.input.localDateField, "YYYY-MM-DD") : null}
            onChange={moment => {
                const i = { ...inputParameters }
                i.input.localDateField = moment?.format("YYYY-MM-DD")
                setInputParameters(i)
            }}
            format="YYYY-MM-DD"
        />
    </Form.Item>


            <Form.Item label="localDateTimeField">
                <DatePicker
                    showTime={{ format: 'HH:mm:ss' }}
                    value={inputParameters.input.localDateTimeField ? moment(inputParameters.input.localDateTimeField.replace("T", " "), "YYYY-MM-DD HH:mm:ss") : null}
                    onChange={moment => {
                        const i = { ...inputParameters }
                        i.input.localDateTimeField = moment?.format("YYYY-MM-DD HH:mm:ss").replace(" ", "T")
                        setInputParameters(i)
                    }}
                    format="YYYY-MM-DD HH:mm:ss"
                />
            </Form.Item>

    <Form.Item label="stringField">
        <Input
            value={inputParameters.input.stringField!}
            onChange={e => {
                const i = { ...inputParameters }
                i.input.stringField = e.target.value
                setInputParameters(i)
            }}
        />
    </Form.Item>

    <Form.Item label="textField">
        <Input
            value={inputParameters.input.textField!}
            onChange={e => {
                const i = { ...inputParameters }
                i.input.textField = e.target.value
                setInputParameters(i)
            }}
        />
    </Form.Item>

        </Form>
    )
}
